// Copyright (C) 2005-2008 Jae Stutzman (jaebird@gmail.com)
//
// This file is part of Podducer.
//
// Podducer is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Podducer is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Podducer.  If not, see <http://www.gnu.org/licenses/>.

// Inspired by http://liveincode.rm.pp.ru/ (Borland Delphi 7)

using System;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

namespace Podducer
{
	public class Program
	{
		private readonly IRecordController recordController;
		private readonly bool runningOnWindows;

		private NotifyIcon notifyIcon;

		MenuItem defaultMenuItem;
		MenuItem recordMenuItem;
		MenuItem pauseMenuItem;
		MenuItem stopMenuItem;

		private ContextMenu menu;
		private FrmMain frmMain;

		private Icon iconStop;
		private Icon iconRecord;
		private Icon iconPause;

		public Program()
		{
			// figure out if we are on windows...
			int p = (int) Environment.OSVersion.Platform;
			if ((p == 4) || (p == 128))
			{
				// use gstreamer on linux
				recordController = new GstreamerRecordController();
			}
			else
			{
				runningOnWindows = true;

				// use directsound on windows...
				recordController = new DirectXRecordController();
			} 
			
			try
			{
				Application.EnableVisualStyles();
				
				recordController.RecordOccured += new ControllerHandler(recordController_RecordOccured);
				recordController.PauseOccured += new ControllerHandler(recordController_PauseOccured);
				recordController.StopOccured += new ControllerHandler(recordController_StopOccured);

				iconStop = new Icon(GetType(),"Resources.iconStop.ico");
				iconRecord = new Icon(GetType(),"Resources.iconRecord.ico");
				iconPause = new Icon(GetType(),"Resources.iconPause.ico");

				defaultMenuItem = new MenuItem("Show", new System.EventHandler(ShowMainForm));
				defaultMenuItem.DefaultItem = true;
				recordMenuItem = new MenuItem("Record",new System.EventHandler(Record_Click));
				pauseMenuItem = new MenuItem("Pause",new System.EventHandler(Pause_Click));
				stopMenuItem = new MenuItem("Stop",new System.EventHandler(Stop_Click));

				pauseMenuItem.Enabled = false;
				stopMenuItem.Enabled = false;

				menu = new ContextMenu();
				menu.MenuItems.Add(0, defaultMenuItem);
				menu.MenuItems.Add(1, new MenuItem("-"));
				menu.MenuItems.Add(2, recordMenuItem);
				menu.MenuItems.Add(3, pauseMenuItem);
				menu.MenuItems.Add(4, stopMenuItem);
				menu.MenuItems.Add(5, new MenuItem("-"));
				menu.MenuItems.Add(6, new MenuItem("Exit", new System.EventHandler(Exit_Click)));

				notifyIcon = new NotifyIcon();
				notifyIcon.Text = "Right click for context menu";
				notifyIcon.Icon = iconStop;
				notifyIcon.ContextMenu = menu;
				notifyIcon.DoubleClick += new EventHandler(ShowMainForm);
				notifyIcon.Visible = true;

				frmMain = new FrmMain(recordController);

				string errorString;
				if (!recordController.StartProcess(out errorString))
				{
					// message why it failed...
				}

				Application.Run();
			}
			finally
			{
				// do any cleanup here...

				if (recordController != null)
				{
					recordController.Dispose();
					recordController = null;
				}
				
				if (notifyIcon != null)
				{
					notifyIcon.Dispose();
					notifyIcon = null;
				}
			
				if (frmMain != null)
				{
					frmMain.Close();
					frmMain = null;
				}
			}

		}

		protected void Record_Click(Object sender, System.EventArgs e) 
		{
			string errorString;
			if(!recordController.StartRecord(out errorString))
			{
				MessageBox.Show("Error starting recording: " + errorString, "Recording Error");
			}
		}

		protected void Pause_Click(Object sender, System.EventArgs e) 
		{
			recordController.PauseOrResume();
		}

		protected void Stop_Click(Object sender, System.EventArgs e) 
		{
			if (MessageBox.Show("Are you sure you want to stop recording?", 
				"Stop Recording", MessageBoxButtons.YesNo) == DialogResult.Yes)
			{
				recordController.StopRecording();
			}
		}
      
		protected void Exit_Click(Object sender, System.EventArgs e) 
		{
			if (recordController.RecordMode != RecordMode.Stopped)
			{
				if (MessageBox.Show("You are recording, are you sure you want to exit?", 
					"Stop Recording", MessageBoxButtons.YesNo) == DialogResult.Yes)
				{
					recordController.RecordOccured -= new ControllerHandler(recordController_RecordOccured);
					recordController.PauseOccured -= new ControllerHandler(recordController_PauseOccured);
					recordController.StopOccured -= new ControllerHandler(recordController_StopOccured);
					
					recordController.StopRecording();
					Application.Exit();
				}
			}
			else
				Application.Exit();
		}

		[STAThread]
		static void Main() 
		{
			// used to allow only one instance of the program to run...
			// create the mutex and if there is not another instance
			// running, go ahead...otherwise exit...
//			Mutex onlyOne = new Mutex(true, Process.GetCurrentProcess().ProcessName);
//			if (onlyOne.WaitOne(0, false))
//			{
//				try
//				{
					new Program();
//				}
//				finally
//				{
//					onlyOne.ReleaseMutex();
//					onlyOne.Close();
//					onlyOne = null;
//				}
//			}
//			else
//			{
//				Console.WriteLine("Another instance of Mr. Podder is already running.");
//			}
		}

		private void ShowMainForm(object sender, EventArgs e)
		{
			frmMain.Show();
		}

		private void recordController_RecordOccured()
		{
			notifyIcon.Icon = iconRecord;

			recordMenuItem.Enabled = false;
			pauseMenuItem.Enabled = true;
			stopMenuItem.Enabled = true;
		}

		private void recordController_PauseOccured()
		{
			if (recordController.RecordMode == RecordMode.Recording)
			{
				// it is recording
				notifyIcon.Icon = iconRecord;
				pauseMenuItem.Text = "Pause";
			}
			else if (recordController.RecordMode == RecordMode.Paused)
			{
				// it is paused...
				notifyIcon.Icon = iconPause;
				pauseMenuItem.Text = "Resume";
			}
		}

		private void recordController_StopOccured()
		{
			if (notifyIcon != null)
			{
				notifyIcon.Icon = iconStop;

				recordMenuItem.Enabled = true;
				pauseMenuItem.Enabled = false;
				stopMenuItem.Enabled = false;
			}
		}
	}

}
